﻿//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description: Validation Rule to validate that the specified cookie is present 
//              as part of the response or request
//
//------------------------------------------------------------------------------
using System;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting;

namespace WebAndLoadTestPluginsAndRules
{
    [DisplayName("Cookie Name and Value")]
    [Description("Validates that the specified cookie is present as part of the response or request")]
    public class ValidateCookie : ValidationRule
    {
        // The Required Cookie Name
        private string cookieName;

        [DisplayName("Required Cookie")]
        [Description("The name of the required cookie.")]
        public string RequiredCookieName
        {
            get { return cookieName; }
            set { cookieName = value; }
        }

        // The value of the cookie
        private string cookieValue;

        [DisplayName("Value ")]
        [Description("The value of the required cookie.")]
        public string SpecifiedCookieValue
        {
            get { return cookieValue; }
            set { cookieValue = value; }
        }

        // Cookie is part of Request or Response
        private bool responseValue = true;

        [DisplayName("Cookie is part of Response")]
        [Description("Whether the cookie is part of the Request or Response")]
        [DefaultValue(true)]
        public bool Response
        {
            get { return responseValue; }
            set { responseValue = value; }
        }

        //  Should the Case be ignored while comparing the value
        private bool ignoreCaseValue = false;

        [DisplayName("Ignore Case")]
        [Description("Whether case should be ignored or not while comparing the cookie.")]
        [DefaultValue(false)]
        public bool IgnoreCase
        {
            get { return ignoreCaseValue; }
            set { ignoreCaseValue = value; }
        }
    
        // Validate is called with the test case Context and the request context.
        // These allow the rule to examine both the request and the response.
        //---------------------------------------------------------------------
        public override void Validate(object sender, ValidationEventArgs e)
        {
            bool validated = false;
            System.Net.Cookie myCookie;
            
            try
            {
                if (cookieName != null && cookieName.Length != 0)
                {
                    //  It's doesn't matter if it's an XML or HTML response
                    if ((Response == true && e.Response.Cookies.Count > 0 && (myCookie = e.Response.Cookies[cookieName]) != null) ||
                        (Response == false && e.Request.Cookies.Count > 0 && (myCookie = e.Request.Cookies[cookieName]) != null))
                    {
                        // Compare the value whether the user has specified a Cookie Value or not
                        if (cookieValue != null && myCookie.Value.Equals(cookieValue, (IgnoreCase == true) ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture))
                        {
                            validated = true;
                        }
                        else
                        {
                            e.Message = String.Format("Expected cookie value: '{0}', Found cookie value: '{1}'", cookieValue, myCookie.Value);
                        }
                    }
                    else
                    {
                        e.Message = String.Format("Could not find a cookie with name '{0}' in the web {1}", cookieName, (Response == true)? "response" : "request");
                    }
                }
                else
                {
                    e.Message = String.Format("Cookie name cannot be empty or null");
                }
                
                e.IsValid = validated;

                // If the validation fails, we're already setting the error text above that the user sees
                
            }
            catch (Exception ex)
            {
                e.IsValid = validated;
                e.Message = String.Format("An exception occurred. Cookie name: '{0}' and Value: '{1}'. Stack Dump: {3}", cookieName, cookieValue, ex);

            }            
        }
        
    }
}